from inspect import signature
from loguru import logger
from functools import wraps
import loguru
import markdown


# 文档树，以模块名为分级的树形结构，如对于函数或类，
# 其导入如 aaa.bbb.func_1，则会构建一个树形字典：
# {'aaa': {'bbb': {'func_1': { ... } } } }
_doc_tree = {}
'''
目前规定一下文档树的规范：
_doc_tree = {
    'module_A': {
        'sub': { sub_doc_tree },  # 子模块文档树
        'functions': ['直接隶属于该模块的函数列表的文档信息'],
        'class': ['直接隶属于该模块的 类 列表的文档信息']
    },
    ...
}
'''


def func_doc(func: callable):
    """
    函数装饰器，用于要加入文档的函数上
    """

    doc = func.__doc__
    module = func.__module__
    name = func.__name__
    full_name = module + '.' + name  # 函数全名，如aaa.bb.func1
    func_sig = signature(func)  # 通过反射获取函数信息

    while True:
        if doc is None or doc.strip() == "":  # 被装饰函数不包含文档
            logger.warning(f"function '{full_name}' not contain document.")
            break
        
        module_struct = module.split('.')  # 接下来判断各级模块是否包含在文档树中

        break


    # print(func.__code__.co_varnames)
    @wraps(func)
    def warrper(*args, **kwargs):
        return func(*args, **kwargs)
    
    return warrper


class ClassDoc(type):
    '''
    元类，用于要加入文档的类上
    代码示例：
    ```python
    class DocTest(metaclass=ClassDoc):
        pass
    ```
    '''
    def __init__(self, class_name, class_bases, class_dict):
        '''
        在该方法内可以控制类的产生
        '''
        if '__doc__' not in class_dict or len(class_dict['__doc__'].strip())==0:  # 实现类必须有文档注释，否则抛出异常
            logger.warning(f"class '{class_name}' not contain document.")
            doc = None
        else:
            doc = class_dict['__doc__']
        
        module = class_dict['__module__']

        # print(class_dict['show_dict'])
        for key, val in class_dict.items():
            if callable(val):
                pass
            elif isinstance(val, (staticmethod, classmethod)):
                val = val.__func__  # 被两种类封装过，所以要取出来
                

        # print(class_name, class_bases, class_dict)
        if not class_name.istitle():  # 实现类名首字母必须大写，否则抛出异常
            raise NameError('类名的首字母必须大写')

        